package reflecting;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Parameter;

import entity.ChildActivity;

public class ClassMessageGetter {

	/**
	 * 获取某个类类信息
	 * @param obj
	 */
	public static void getMethodMessage(Object obj){
		
		//获取方法
		//1.getMethods()获取该类所有public，包括父类的public方法
		//2.getDeclaredMethods()获取当前类（不含父类）的所有方法（与方法访问权限无关）
		System.out.println("1.getMethods()获取该类所有public，包括父类的public方法\n");
		Class cls = obj.getClass();
		Method[] methods = cls.getMethods();
		Method[] declaredMethods = cls.getDeclaredMethods();
		for(Method method : methods){
			//通过method.getReturnType().getName()获取返回值名称
			//通过method.getName()获取方法名称
			int modifiers = cls.getModifiers();
			System.out.print(Modifier.toString(method.getModifiers())+" "+method.getReturnType().getName() + " " + method.getName()+"(");
			//通过method.getParameterTypes();获取方法参数的类类型
			Class[] parameterTypes = method.getParameterTypes();
			//通过method.getParameters()获取方法参数
			Parameter[] parameters = method.getParameters();
			for(int  i = 0 ; i < parameterTypes.length ; i ++){
				System.out.print(parameterTypes[i].getSimpleName() + " " +parameters[i].getName()+ (i!=parameterTypes.length-1?",":""));
			}
			System.out.println(")");
		}
		
		System.out.println("\n-----------------------------------------------------------\n");
		System.out.println("2.getDeclaredMethods()获取当前类（不含父类）的所有方法（与方法访问权限无关）\n");
		
		for(Method method : declaredMethods){
			System.out.println(method.getName());
		}
		
	}
	
	/**
	 * 获取类成员变量信息
	 * @param obj
	 */
	public static void getFieldMessage(Object obj){
		Class cls = obj.getClass();
		//1.getFields()获取该类所有public，包括父类的public成员变量
		Field[] fields = cls.getFields();
		//2.getDeclaredFields()获取当前类（不含父类）的所有成员变量（与变量访问权限无关）
		Field[] declaredFields = cls.getDeclaredFields();
		System.out.println("cls.getFields() 获取该类所有public，包括父类的public成员变量");
		for (Field field : fields) {
			System.out.println(field.getType().getSimpleName() + " "+field.getName());
		}
		
		System.out.println("\ngetDeclaredFields()获取当前类（不含父类）的所有成员变量（与变量访问权限无关）");
		for (Field field : declaredFields) {
			System.out.println(field.getType().getSimpleName() + " "+field.getName());
		}
	}
	
	/**
	 * 获取构造函数信息
	 * @param obj
	 */
	public static void getConstructorMessage(Object obj){
		Class cls = obj.getClass();
		Constructor[] constructors = cls.getConstructors();
		Constructor[] declaredConstructors = cls.getDeclaredConstructors();
		
		for (Constructor constructor : constructors) {
			System.out.println(constructor.getName());
		}
		
		System.out.println("------------------");
		for (Constructor constructor : declaredConstructors) {
			System.out.println(constructor.getName());
		}
		
		
	}
	
	
	/**
	 * 通过反射操作方法和成员变量
	 */
	public  static void reflectionProcess(){
		
		ChildActivity ca = new ChildActivity(0);
		Class cls = ca.getClass();
		try {
			//修改filed值
			//1.获取intField成员变量
			Field declaredField = cls.getDeclaredField("intField");
			//2.因为该成员变量是private，此时我们应该先设置为可操作
			declaredField.setAccessible(true);
			//3.赋值
			declaredField.set(ca, 5);
			
			//反射调用方法
			//1.获取目标方法plus(int i)
			Method method  = cls.getDeclaredMethod("plus", int.class);
			//因为该方法是public的，因此不需要调用 method.setAccessible(true);
			//2.调用method.invoke(对象,参数列表)
			method.invoke(ca, 6);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
}
